<?php
declare (strict_types=1);

namespace app\admin\middleware;

use app\admin\controller\Token;
use app\admin\model\Admin;
use app\admin\model\Role;
use app\admin\service\Token as TokenService;
use app\admin\service\Auth as AuthService;
use app\admin\service\Menu as MenuService;
use app\lib\exception\Menu;
use app\lib\exception\Menu as MenuException;
use app\lib\exception\Parameter;
use app\lib\exception\TokenException;
use app\lib\exception\Admin as AdminException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Session;

// 验证登录与否
class Auth
{
    /**
     * @throws Parameter
     * @throws TokenException|AdminException
     */
    public function handle($request, \Closure $next)
    {
        //测试环境模拟成功，不改变数据
        // if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST' || strtoupper($_SERVER['REQUEST_METHOD']) == 'PUT' || strtoupper($_SERVER['REQUEST_METHOD']) == 'DELETE') {
        //     return json(['code' => 20000, 'message' => '测试环境模拟成功，不改变数据', 'data' => null]);
        // }

        $token = $this->checkToken($request);
        $request->uid = $token['user_id'];
        Session::set('admin_id', $token['user_id']);
//        var_dump($token);exit();
        $this->checkAuth($request);
        return $next($request);
    }

    /**
     * 验证token
     * @throws TokenException
     */
    protected function checkToken($request)
    {
        $headers = getallheaders();
        if (!isset($headers['X-Token'])) {
            throw new TokenException();
        } else {
            //验证token
            $token = TokenService::checkPrimaryScope($headers['X-Token'], 'admin');
            $token_time = strtotime($token['update_time']);
            if (!env('APP_DEBUG')) {
                if (time() - $token_time > 86400) {
                    TokenService::refreshUserToken($token['user_id'], 'admin');
                }
            }
            return $token;
//            $request->uid = $token['user_id'];
        }
    }

    /**
     * @throws Menu
     * @throws DataNotFoundException
     * @throws AdminException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    protected function checkAuth($request)
    {
        $user = (new Admin())->where('id=' . $request->uid)->where('status', 1)->findOrEmpty();
        if ($user->isEmpty()) throw new AdminException();
        $role = (new Role())->whereIn('id', $user->role_ids)->select();
        if ($role->isEmpty()) throw new MenuException();
        $roleList = '';
        // 对数据集进行遍历操作
        foreach ($role as $key => $user) {
            if ($key != 0) {
                $roleList = $roleList . ',' . $user->menu_id;
            } else {
                $roleList = $user->menu_id;
            }
        }
        $pathData = [
            'module' => app('http')->getName(),
            'controller' => $request->controller(),
            'action' => $request->action(),
        ];
//        字符串去重
        $roleList = AuthService::unique($roleList);
//        权限验证
        MenuService::verifyMenu($pathData, $roleList);
    }


}
